﻿using Kang.DbDoc.Interfaces;
using Kang.DbDoc.Models;
using Kang.ExtendMethod;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Kang.DbDoc.ServicesImpl
{
    public class MarkdownExportService : IExport
    {
        public bool Export(string filename, DatabaseModel database, List<TableOrViewModel> tables, List<TableOrViewModel> views, List<RoutineModel> functions, List<RoutineModel> procedures, ref string error)
        {
            try
            {
                int m_i = 1;
                using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        if (database.DatabaseType == Enums.DatabaseTypeEnum.SQLite)
                        {
                            sw.WriteLine($"# {Path.GetFileName(database.DatabaseName)}表结构文档{Environment.NewLine}");
                        }
                        else
                        {
                            sw.WriteLine($"# {database.DatabaseName}表结构文档{Environment.NewLine}");
                        }
                        sw.WriteLine($"## {GetChineseNum(m_i++)}、数据库信息{Environment.NewLine}");
                        if (database.DatabaseType == Enums.DatabaseTypeEnum.SQLite)
                        {
                            sw.WriteLine($"`地址：`{database.DatabaseName}");
                        }
                        else
                        {
                            sw.WriteLine($"`地址：`{database.DatabaseHost}");
                        }
                        if (database.DatabasePort > 0)
                        {
                            sw.WriteLine($"`端口：`{database.DatabasePort}");
                        }
                        if (tables.IsNotBlank())
                        {
                            sw.WriteLine($"`表总数：`{tables.Count}");
                        }
                        if (views.IsNotBlank())
                        {
                            sw.WriteLine($"`视图总数：`{views.Count}");
                        }
                        if (functions.IsNotBlank())
                        {
                            sw.WriteLine($"`方法总数：`{functions.Count}");
                        }
                        if (procedures.IsNotBlank())
                        {
                            sw.WriteLine($"`存储过程总数：`{procedures.Count}");
                        }
                        sw.WriteLine($"");
                        sw.WriteLine($"## {GetChineseNum(m_i++)}、修订日志{Environment.NewLine}");
                        sw.WriteLine($"版本号|修订日期|修订内容|修订人|审核人");
                        sw.WriteLine($":--|:--|:--|:--|:--");
                        sw.WriteLine($" | | | |");
                        
                        if (tables.IsNotBlank())
                        {
                            sw.WriteLine($"");
                            sw.WriteLine($"## {GetChineseNum(m_i++)}、表信息{Environment.NewLine}");
                            for (int i = 0, id = 1; i < tables.Count; i++, id = 1)
                            {
                                var table = tables[i];
                                if (i > 0)
                                {
                                    sw.WriteLine($"----{Environment.NewLine}");
                                }
                                sw.WriteLine($"### 表：{table.Name}");
                                if (table.Comment.IsNotBlank())
                                {
                                    sw.WriteLine($"> {table.Comment}{Environment.NewLine}");
                                }
                                sw.WriteLine($"序号|列名|数据类型|长度|小数|键类型|自增|为空|默认|列说明");
                                sw.WriteLine($":--|:--|:--|:--|:--|:--|:--|:--|:--|:--");
                                foreach (var col in table.Columns)
                                {
                                    sw.WriteLine($"{id++}" +
                                                 $"|{col.Name}" +
                                                 $"|{col.Type}" +
                                                 $"|{col.Length}" +
                                                 $"|{col.Scale}" +
                                                 $"|{col.KeyType}" +
                                                 $"|{(col.IsAutoIncrement ? "√" : "")}" +
                                                 $"|{(col.IsNull ? "√" : "")}" +
                                                 $"|{col.Default}" +
                                                 $"|{col.Comment}");
                                }
                                sw.WriteLine($"");
                            }
                        }
                        
                        if (views.IsNotBlank())
                        {
                            sw.WriteLine($"");
                            sw.WriteLine($"## {GetChineseNum(m_i++)}、视图信息{Environment.NewLine}");
                            for (int i = 0, id = 1; i < views.Count; i++, id = 1)
                            {
                                var view = views[i];
                                if (i > 0)
                                {
                                    sw.WriteLine($"----{Environment.NewLine}");
                                }
                                sw.WriteLine($"### 视图：{view.Name}");
                                if (view.Comment.IsNotBlank())
                                {
                                    sw.WriteLine($"> {view.Comment}{Environment.NewLine}");
                                }
                                sw.WriteLine($"序号|列名|数据类型|长度|小数|键类型|自增|为空|默认|列说明");
                                sw.WriteLine($":--|:--|:--|:--|:--|:--|:--|:--|:--|:--");
                                foreach (var col in view.Columns)
                                {
                                    sw.WriteLine($"{id++}" +
                                                 $"|{col.Name}" +
                                                 $"|{col.Type}" +
                                                 $"|{col.Length}" +
                                                 $"|{col.Scale}" +
                                                 $"|{col.KeyType}" +
                                                 $"|{(col.IsAutoIncrement ? "√" : "")}" +
                                                 $"|{(col.IsNull ? "√" : "")}" +
                                                 $"|{col.Default}" +
                                                 $"|{col.Comment}");
                                }
                                sw.WriteLine($"");
                            }
                        }
                        
                        if (functions.IsNotBlank())
                        {
                            sw.WriteLine($"");
                            sw.WriteLine($"## {GetChineseNum(m_i++)}、方法信息{Environment.NewLine}");
                            for (int i = 0; i < functions.Count; i++)
                            {
                                var function = functions[i];
                                if (i > 0)
                                {
                                    sw.WriteLine($"----{Environment.NewLine}");
                                }
                                sw.WriteLine($"`方法：`{function.Name}");
                                sw.WriteLine($"`创建者：`{function.Definer}");
                                if (function.Comment.IsNotBlank())
                                {
                                    sw.WriteLine($"> {function.Comment}{Environment.NewLine}");
                                }
                                sw.WriteLine($"```sql");
                                sw.WriteLine($"{function.Definition}");
                                sw.WriteLine($"```{Environment.NewLine}");
                            }
                        }
                        
                        if (procedures.IsNotBlank())
                        {
                            sw.WriteLine($"");
                            sw.WriteLine($"## {GetChineseNum(m_i++)}、存储过程信息{Environment.NewLine}");
                            for (int i = 0; i < procedures.Count; i++)
                            {
                                var procedure = procedures[i];
                                if (i > 0)
                                {
                                    sw.WriteLine($"----{Environment.NewLine}");
                                }
                                sw.WriteLine($"`存储过程：`{procedure.Name}");
                                sw.WriteLine($"`创建者：`{procedure.Definer}");
                                if (procedure.Comment.IsNotBlank())
                                {
                                    sw.WriteLine($"> {procedure.Comment}{Environment.NewLine}");
                                }
                                sw.WriteLine($"```sql");
                                sw.WriteLine($"{procedure.Definition}");
                                sw.WriteLine($"```{Environment.NewLine}");
                            }
                        }
                    }
                }
                return true;
            }
            catch (Exception e)
            {
                error = e.Message;
                return false;
            }
        }

        public string GetChineseNum(int i)
        {
            switch (i)
            {
                case 0:
                    return "〇";
                case 1:
                    return "一";
                case 2:
                    return "二";
                case 3:
                    return "三";
                case 4:
                    return "四";
                case 5:
                    return "五";
                case 6:
                    return "六";
                case 7:
                    return "七";
                case 8:
                    return "八";
                case 9:
                    return "九";
                case 10:
                    return "十";
                case 11:
                    return "十一";
                case 12:
                    return "十二";
            }
            return string.Empty;
        }
    }
}
